package com.simple.datax.compress.impl;

import org.apache.xmlbeans.XmlObject;

import com.alibaba.dubbo.common.io.Bytes;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.simple.datax.SimpleMessage;
import com.simple.datax.api.CommonSimpleException;
import com.simple.datax.api.SimpleException;
import com.simple.datax.api.Transformer;
import com.simple.datax.service.AbstractMessageProcessor;
import com.simple.datax.utils.MessageGZIP;
import com.simple.datax.utils.MessageZIP;
import com.simple.datax.utils.SimpleConstants;
import com.simple.datax.xml.ec.EC101MessageDocument;
import com.simple.datax.xml.ec.EC101MessageDocument.EC101Message;
import com.simple.datax.xml.ec.EC101ResponseDocument;
import com.simple.datax.xml.tcs.TCS101MessageDocument;
import com.simple.datax.xml.tcs.TCS101MessageDocument.TCS101Message;
import com.simple.datax.xml.tcs.TCS101ResponseDocument;

/**
 * @Title: MessageCompressImpl.java
 * @Package com.simple.datax.compress.impl
 * @Description: 参照MessageUnCompressImpl
 * 
 *               对于需要压缩的判断，目前按如下方式实现： 1、 必须收到的报文头中compress为true 2、
 *               发送至本Node的内部处理list中ID的
 *               ，都不处理；（这一项只用在Router中配置了，内部处理和其他企业采用同样的通讯方式时才能用到） 3、
 *               发送到本Node的其他ID都要处理率； 4、 发送到其他Node的都要处理；
 * 
 * 
 * @author Paladin Chen
 * @date 2013-1-10 下午1:34:17
 * @version V1.0
 */
public class MessageCompressImpl extends AbstractMessageProcessor implements Transformer {
	private static final Logger logger = LoggerFactory.getLogger(MessageCompressImpl.class);

	private String compressType = "gzip";

	@Override
	public void realProcess(SimpleMessage src) throws SimpleException {
		logger.debug("Begin to Compress....." + src.toLog());

		try {
			setErrorInfos(SimpleConstants.ERROR_TYPE_DATAXPROC, SimpleConstants.ERROR_LEVEL_NORMAL,
					SimpleConstants.RESPONSE_CODE_COMPRESS, SimpleConstants.RESPONSE_MSG_COMPRESS);

			// 如果上来的是压缩报文，出去的报文需要压缩

			if (checkNeedCompress(src)) {
				compress(src);
			}

			callNextStep(src);
		} catch (Exception e) {
			throw new CommonSimpleException("Compress Error:" + e.getMessage(), e);
		}

		logger.debug("Finish Compress....." + src.toLog());
	}

	// 检查发出报文是否需要压缩
	private boolean checkNeedCompress(SimpleMessage src) {
		// if (src.isCompress()) {
		// if (localNode.equalsIgnoreCase(src.getReceiverNode())) {
		// String receiver = src.getReceiver().toUpperCase();
		//
		// if (intraProcCode.contains(receiver)) {
		// return false;
		// }
		// }
		// return true;
		// }
		// return false;
		compressType = src.getSentMsgFormat();
		if ("GZIP".equalsIgnoreCase(compressType) || "ZIP".equalsIgnoreCase(compressType)) {
			return true;
		}
		return false;
	}

	private void compress(SimpleMessage src) throws CommonSimpleException {
		if (src.getIntraDoc() != null) {
			XmlObject iDoc = src.getIntraDoc();
			try {
				if (iDoc instanceof EC101MessageDocument) {
					EC101Message ecmsg = ((EC101MessageDocument) iDoc).getEC101Message();

					String unCompressContent = ecmsg.getMessageBody().xmlText();

					String compressContent = compress(unCompressContent);

					ecmsg.setMessageBody(com.simple.datax.xml.ec.XMLDATA.Factory.parse(compressContent));
				} else if (iDoc instanceof EC101ResponseDocument) {
					// 暂不支持
					logger.info("EC101ResponseDocument not support Compress Now!!");
					// EC101Response ecres = ((EC101ResponseDocument)
					// iDoc).getEC101Response();
					// String compressType =
					// ecres.getMessageBody().getDomNode().getFirstChild().getNodeName();
					// String compressContent =
					// ecres.getMessageBody().getDomNode().getFirstChild().getNodeValue();
					// String unCompressContent = uncompress(compressContent,
					// compressType);
					//
					// ecres.setMessageBody(EC101Response.MessageBody.Factory.parse(unCompressContent));
					//
					// com.simple.datax.xml.tcs.XMLDATA;
				} else if (iDoc instanceof TCS101MessageDocument) {
					TCS101Message tcsmsg = ((TCS101MessageDocument) iDoc).getTCS101Message();

					String unCompressContent = tcsmsg.getMessageBody().xmlText();

					String compressContent = compress(unCompressContent);

					tcsmsg.setMessageBody(com.simple.datax.xml.tcs.XMLDATA.Factory.parse(compressContent));
				} else if (iDoc instanceof TCS101ResponseDocument) {
					logger.info("TCS101ResponseDocument not support Compress Now!!");
				} else {
					// 不做处理
					logger.info("Unkown Document not support Compress Now!!");
				}
			} catch (Exception e) {
				throw new CommonSimpleException(e.getMessage(), e);
			}
		}
	}

	private String compress(String content) throws Exception {
		if (content == null) {
			return null;
		}

		if ("gzip".equalsIgnoreCase(compressType)) {
			return "<GZIP>" + Bytes.bytes2hex(MessageGZIP.compressToByte(content)) + "</GZIP>";
		} else if ("zip".equalsIgnoreCase(compressType)) {
			return "<ZIP>" + Bytes.bytes2hex(MessageZIP.compressToByte(content)) + "</ZIP>";
		} else {
			return content;
		}
	}

	public void compresst(SimpleMessage src) {
		try {
			compress(src);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
